#include "apue.h"
#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>

void daemonize(const char *cmd) {
    int i, fd0, fd1, fd2;
    pid_t pid;
    struct rlimit rl;
    struct sigaction sa;

    /**
     * Clear file creation mask
     */
    umask(0);
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        err_quit("%s: cant get file limit", cmd);

    if ((pid= fork()) < 0) 
        err_quit("%s: cant fork", cmd);
    if (pid > 0) /* parent */
        exit(0);

    //char kk[100];
    //if (fgets(kk, 100, stdin) == NULL) {
    //    printf("kakakxixix");
    //}
    
    setsid();

    /**
     * 1. setsid 以后的代码不会被交互式 shell 的断开（SIGHUP）产生 SIGHUP
     * ，因为当前已经和交互式 shell 不处于同一个 session 了
     * ，所以这里的守护进程可能是防止用户误发送 SIGHUP，因为 SIGHUP 被
     * 很多守护进程用于重载配制文件；但是用户毕竟是发送了 SIGHUP
     * 2. 有些守护进程会在创建会话后读取终端，这里忽略 SIGHUP 是防止终止意义断开发送 SIGHUP 给首进程
     */
    sa.sa_handler= SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags= 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        err_quit("%s: cant ignore SIGHUP", cmd);

    if ((pid= fork()) < 0)
        err_quit("%s: cant fork", cmd);
    if(pid > 0)
        exit(0);

    /**
     * Change the current working directory to the root so 
     * we won't prevent file systems from being unmounted.
     */
    if (chdir("/") < 0)
        err_quit("%s: cant change directory to /", cmd);

    /**
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max= 1024;
    for (i=0; i<rl.rlim_max; ++i)
        close(i);

    /**
     * Attach file descriptors 0, 1, and 2 to /dev/null
     */
    fd0= open("/dev/null", O_RDWR);
    fd1= dup(fd0);
    fd2= dup(fd0);

    /**
     * Initialize the log file
     */
    openlog(cmd, LOG_CONS, LOG_DAEMON);
    if (fd0 != 0|| fd1 != 1 || fd2 != 2) {
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2) ;
        exit(1);
    }

    char *name;
    name= getlogin();
    syslog(LOG_INFO, "current login user [%s] in daemon process", name) ;

}

int main(void) {
    daemonize("practice_13.4.c");
}
